package visualization;

import java.awt.Dimension;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import model.WebHistoryModel;
import view.WebHistoryException;
import visualization.graphkeymodel.circlechart.CircleChart;


/**
 * Factory class to generate Visualizations. The only thing Visualizations
 * must have in common is that they take a PairList and a Dimension in their
 * constructor.
 * @author Niel Lebeck
 *
 */
public final class VisualizationFactory {
    private static final int PREFERRED_WIDTH = 800;
    private static final int PREFERRED_HEIGHT = 600;

    private VisualizationFactory () {

    }

    /**
     * Create a new Visualization with the given view type and pairList using
     * reflection.
     * @param viewType type of view to create
     * @param pairList list of pairs
     * @throws WebHistoryException errors in reflection
     * @return
     */
    public static Visualization createVisualization
    (String viewType, List<PairEntry<String, Double>> pairList)
        throws WebHistoryException {
        ResourceBundle myResources = ResourceBundle.getBundle("resources.WebHistory");
        Visualization result = null;

        //use reflection to instantiate the Visualization
        String className = null;
        try {
            className = myResources.getString(viewType);
        }
        catch (MissingResourceException e) {
            throw new WebHistoryException("invalid visualization name");
        }
        Constructor<?> c = getVisualizationConstructor(className);
        try {
            result = (Visualization)c.newInstance(
                    pairList, new Dimension(PREFERRED_WIDTH, PREFERRED_HEIGHT));
        }
        catch (IllegalArgumentException e) {
            throw new WebHistoryException("illegal number of arguments for constructor");
        }
        catch (InstantiationException e) {
            throw new WebHistoryException("illegal instantiation");
        }
        catch (IllegalAccessException e) {
            throw new WebHistoryException("illegal access");
        }
        catch (InvocationTargetException e) {
            throw new WebHistoryException("illegal invocation target using command");
        }
        return result;
    }



    private static Constructor<?> getVisualizationConstructor(String className)
        throws WebHistoryException {
        Constructor<?>[] constructList = null;

        try {
            constructList = Class.forName(className).getDeclaredConstructors();
        }
        catch (SecurityException e) {
            throw new WebHistoryException("security exception");
        }
        catch (ClassNotFoundException e) {
            throw new WebHistoryException("class not found");
        }

        for (Constructor<?> c : constructList) {
            if (c.getParameterTypes().length == 2) {
                return c;
            }
        }
        return null;
    }

}
